﻿/*
 * 由SharpDevelop创建。
 * 用户： Dandjinh Deng
 * 日期: 2018/7/6
 * 时间: 10:16
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO.Ports;

namespace CdcTest
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		const double TIMER_INTERVAL = 1000.0;
		
		SerialPort comport = new SerialPort();
		private System.Timers.Timer timer = new System.Timers.Timer(TIMER_INTERVAL);
		bool isPortOpen = false;
		long bytesCount = 0;
		
		public delegate void UpdateSpeedText(long count);
		public UpdateSpeedText doUpdateSpeedText;
		
		public delegate void ShowErrorMessage(string text);
		public ShowErrorMessage doShowErrorMessage;
		
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
			InitComport();
			InitTimer();
			
			CBport.DropDownStyle = ComboBoxStyle.DropDownList;
		}
		
		void InitComport()
		{
			comport.BaudRate = 115200;
			comport.Parity = Parity.None;
			comport.DataBits = 8;
			comport.StopBits = StopBits.One;
			comport.Handshake = Handshake.None;
			
			comport.ReadTimeout = 200;
			comport.WriteTimeout = 200;
			
			comport.ReadBufferSize = 1024 * 1024;
			comport.WriteBufferSize = 1024;
			
			comport.DataReceived += OnReceivedPortData;
			comport.ReceivedBytesThreshold = 8 * 1024;
			
			doShowErrorMessage = new ShowErrorMessage(OnShowErrorMessage);
		}
		
		public void OnReceivedPortData(object sender, SerialDataReceivedEventArgs e)
		{
			var len = comport.BytesToRead;
			bytesCount += len;
			var b = new byte[len];
			try {
				comport.Read(b, 0, len);
			} catch (InvalidOperationException ex) {
				doShowErrorMessage(ex.Message);
			}
		}
		
		void InitTimer()
		{
			timer.Elapsed += OnTimerEvent;
			timer.AutoReset = true;
			timer.Enabled = false;
			
			doUpdateSpeedText = new UpdateSpeedText(OnUpdateSpeedText);
		}
		
		public void OnTimerEvent(object source, System.Timers.ElapsedEventArgs e)
		{
			long count = bytesCount;
			bytesCount = 0;
			Invoke(doUpdateSpeedText, count);
		}
		
		public void OnUpdateSpeedText(long count)
		{
			string text;
			if (count >= 1024 * 1024) {
				text = String.Format("{0:N3} MB/s", count / (1024.0 * 1024.0));
			} else if (count >= 1024) {
				text = String.Format("{0:N3} KB/s", count / 1024.0);
			} else {
				text = String.Format("{0} B/s", count);
			}
			TBspeed.Text = text;
		}
		
		public void OnShowErrorMessage(string text)
		{
			ClosePort();
			MessageBox.Show(text);
		}
		
		void BtnClick(object sender, EventArgs e)
		{
			if (isPortOpen) {
				ClosePort();
			} else {
				if (CBport.SelectedIndex < 0) return;
				
				comport.PortName = (String) CBport.SelectedItem;
				OpenPort();
			}
		}
		
		void ClosePort()
		{
			timer.Stop();
			comport.Close();
			isPortOpen = false;
			btn.Text = "打开";
		}
		
		void OpenPort()
		{
			try {
				comport.Open();
				bytesCount = 0;
				timer.Start();
				isPortOpen = true;
				btn.Text = "关闭";
			} catch (Exception ex) {
				MessageBox.Show(ex.Message);
			}
		}
		
		void CBportDropDown(object sender, EventArgs e)
		{
			CBport.Items.Clear();
			String[] names = SerialPort.GetPortNames();
			foreach (var n in names) {
				CBport.Items.Add(n);
			}
		}
		
		void MainFormFormClosing(object sender, FormClosingEventArgs e)
		{
			if (comport.IsOpen)
				comport.Close();
		}
	}
}
